package com.itbac.controller;

import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.itbac.config.sentinel.Message5BlockHandler;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * 测试 Sentinel
 * 1.限流，限制别人访问自己
 * 2.降级，限制自己访问别人。
 * 3.热点规则流控，对指定请求参数限流
 * 4.自定义异常处理方法
 * 5.自定义异常处理类
 */

@RestController
@RequestMapping("/sentinel")
public class SentinelTestController {

    // http://127.0.0.1:8091/sentinel/message1
    @RequestMapping("/message1")
    public String getMessage(){
        return "message1";
    }
    @RequestMapping("/message2")
    public String getMessage2(){
        return "message2";
    }
    @RequestMapping("/message3")
    //标注这是一个资源,要被sentinel管理,才能使用热点流控规则
    @SentinelResource("message3")
    public String getMessage3(String name ,String age){
        return String.format("message3,name:{%s},age:{%s}", name, age);
    }

    /**
     * SentinelResource 捕获资源内部的异常 （在当前类，定义异常处理方法）
     * blockHandler ： 捕获 sentinel 内部的5种异常，执行对应方法。
     * fallback ： 捕获 资源内部的 Throwable ,执行对应方法。
     * 要求：定义的异常处理方法,参数与返回值与资源方法相同。
     */
    @RequestMapping("/message4")
    @SentinelResource(
            value = "message4",
            blockHandler = "getMessage4BlockHandler",
            fallback = "getMessage4Fallback"
    )
    public String getMessage4(String name) {
        return "message4,name:" + name;
    }
    /**
     * blockHandler
     * 要求：
     * 1、当前方法的返回值和参数，与原方法一致。
     * 2、允许在参数列表的最后加入一个参数 BlockException （sentinel定义的5种异常） ，用来接收原方法中的异常。
     */
    public String getMessage4BlockHandler(String name, BlockException e) {
        return "getMessage4BlockHandler异常方法";
    }
    /**
     * fallback
     * 要求：
     * 1、当前方法的返回值和参数，与原方法一致。
     * 2、允许在参数列表的最后加入一个参数 Throwable （所有异常） ，用来接收原方法中的异常。
     */
    public String getMessage4Fallback(String name, Throwable e) {
        return "getMessage4Fallback异常方法";
    }
    /**
     * @see Message5BlockHandler
     * 在别的类，定义异常处理方法，需要指定类名。定义异常处理方法必须是静态方法
     */
    @RequestMapping("/message5")
    @SentinelResource(
            value = "message5",
            blockHandlerClass = Message5BlockHandler.class,
            blockHandler= "getMessage5BlockHandler",
            fallbackClass = Message5BlockHandler.class,
            fallback = "getMessage5Fallback"
    )
    public String getMessage5(String name) {
        return "message5,name:" + name;
    }
}
